<?php
// +----------------------------------------------------------------------
// | Bwsaas
// +----------------------------------------------------------------------
// | Copyright (c) 2015~2020 http://www.buwangyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Gitee ( https://gitee.com/buwangyun/bwsaas )
// +----------------------------------------------------------------------
// | Author: buwangyun <hnlg666@163.com>
// +----------------------------------------------------------------------
// | Date: 2020-9-28 10:55:00
// +----------------------------------------------------------------------

namespace app\common\model;

use buwang\base\BaseModel;
use buwang\traits\JwtTrait;

/**
 * 成员应用表
 * Class
 * @package app\manage\model
 */
class User extends BaseModel
{
    use JwtTrait;

    /**
     * 判断invite_code用户是否存在
     *
     */
    public static function isInvite($invite_code, $member_miniapp_id = null)
    {
        if (empty($invite_code)) {
            return;
        }
        $id = de_code(strtoupper($invite_code));
        $self = new self;
        if ($member_miniapp_id) $self = $self->where('member_miniapp_id', $member_miniapp_id);
        $is_invite = $self->where(['id' => $id])->field('id')->find();
        return empty($is_invite) ? 0 : $is_invite['id'];
    }

    public static function checkPassword($password, $safePassword)
    {
        //TODO：验证安全密码
        if (password_verify(md5($password), $safePassword)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 驗證用戶信息
     *
     */
    public static function validateUser($username, $password, $member_miniapp_id = null)
    {
        //判断用户是否存在
        $self = self::where('username|mobile', $username);
        if ($member_miniapp_id) $self = $self->where('member_miniapp_id', $member_miniapp_id);
        $userInfo = $self->find();
        if (!$userInfo) return self::setError('用户名或密码错误');
        if ($userInfo['status'] == 0) return self::setError('账号已被封禁无法登陆');
        //得到加密后的密码
        if (!self::checkPassword($password, $userInfo['password'])) return self::setError('用户名或密码错误');
        return $userInfo;
    }

    /**
     * 登錄用戶User
     * @param $user
     * @param $scopes
     * @param bool $trans
     * @return array|bool
     */
    public static function loginUser($user, $scopes, $trans = false)
    {
        if (!in_array($scopes, ['mini_program', 'app', 'h5', 'official'])) return self::setError('scopes類型錯誤');
        if ($trans) {
            self::startTrans();
        }
        $res = $res1 = $res2 = $tokenInfo = true;
        try {
            $data = [
                'id' => $user['id'],
                'nickname' => $user['nickname'] ?: '',
                'mobile ' => $user['mobile'] ?: '',
            ];
            $tokenInfo = self::getAccessToken($data, $scopes);
            //存儲token相关信息
            // $res2 = Token::updateToken($user['id'], $tokenInfo['token'], 'admin');
            //更新用户登录信息
            $user->login_time = time();
            $user->login_ip = request()->ip();
            $res1 = $user->save();

            $res = $res1 && $res2 && $tokenInfo && true;
            if ($trans) {
                self::checkTrans($res);
            }
            // TODO 用户登录成功后事件
            event('UserLoginSuccess', [$user, $scopes]);
        } catch (\Exception $e) {
            if ($trans) {
                self::rollback();
            }
            return self::setError($e->getMessage());
        }
        if (!$tokenInfo) return self::setError('获取AccessToken或存储失败');
        if (!$res1) return self::setError('更新用户登录信息失败');
        if (!$res2) return self::setError('更新用户验证信息失败');
        return $tokenInfo;
    }

//    /**
//     * 通过微信注册或更新（旧）
//     * @param array $wechat
//     * @param int $is_miniapp true小程序  fasle公众号
//     * @return 成功后返回用户的ID
//     */
//    public static function wechatReg(array $wechat, $is_miniapp = true)
//    {
//        //参数
//        $data = [];
//        $updata = [];
//        $type = 'mini_program';//小程序
//        $data['member_miniapp_id'] = $wechat['miniapp_id'];//MemberMiniapp表id
//        $data['nickname'] = $wechat['nickname'];//昵称
//        $data['avatar'] = $wechat['avatar']; //头像
//        $data['unionid'] = $wechat['unionid'];//unionid
//        $data['login_time'] = time(); //登陆时间
//        $data['update_time'] = time(); //更新时间
//        $data['login_ip'] = request()->ip();  //登录ip
//        if ($is_miniapp) {//小程序
//            $data['session_key'] = $wechat['session_key']; //小程序session_key
//            $data['miniapp_uid'] = $wechat['miniapp_uid']; //小程序用户id
//            !empty($wechat['official_uid']) && $data['official_uid'] = $wechat['official_uid'];
//        } else {//公众号
//            $data['official_uid'] = $wechat['official_uid'];//公众号openid
//            $type = 'official';//公众号
//        }
//        //查询用户$condition查询条件
//        $condition['member_miniapp_id'] = $wechat['miniapp_id']; //区分哪个应用
//        $userModel = self::where($condition)->where("unionid <> '' OR official_uid <> '' OR miniapp_uid <> '' OR mobile <> ''");
//        isset($wechat['unionid']) && $wechat['unionid'] && $userModel = $userModel->where('unionid', $wechat['unionid']);
//        isset($wechat['official_uid']) && $wechat['official_uid'] && $userModel = $userModel->where('official_uid', $wechat['official_uid']);
//        isset($wechat['miniapp_uid']) && $wechat['miniapp_uid'] && $userModel = $userModel->where('miniapp_uid', $wechat['miniapp_uid']);
//        isset($wechat['mobile']) && $wechat['mobile'] && $userModel = $userModel->where('mobile', $wechat['mobile']);
//        $info = $userModel->findOrEmpty();
//
//        if ($info->isEmpty()) {//新注册用户
//            $is_insert = true;
//            //用户在小程序应用设置里面进行公众号绑定操作
//            if ($is_miniapp && !empty($wechat['official_uid'])) {
//                $official_info = self::where(['member_miniapp_id' => $wechat['miniapp_id'], 'miniapp_uid' => $wechat['miniapp_uid']])->find();
//                if ($official_info) {
//                    $is_insert = false;
//                    $last_id = $official_info['id'];
//                    self::update(['id' => $last_id, 'official_uid' => $wechat['official_uid']]);
//                }
//            }
//            //判断是否需要插入数据
//            if ($is_insert) {
//                $data['create_time'] = time();
//                $is_invite = $wechat['invite_code'] ? self::isInvite($wechat['invite_code'], $wechat['miniapp_id']) : false;  //查邀请码是否有效
//                if ($is_invite) {
//                    $data['pid'] = de_code($wechat['invite_code']);//注册用户加入上级推荐人
//                }
//                $last_id = self::insertGetId($data);
//                if ($last_id) {
//                    self::where('id', $last_id)->data(['invite_code' => en_code($last_id)])->update();//每个人的邀请码是根据ID生成的可解密code
//                    /**-------------20200910 jyk 注册成功后创建对应应用的用户副表 start-----------------**/
//                    $user = self::find($last_id);
//                    //用户注册成功后事件
//                    event('UserRegisterSuccess', [$user, $type]);
//                    /**-------------20200910 jyk 注册成功后创建对应应用的用户副表 end-----------------**/
//                }
////                //添加用户邀请来源
////                if(!empty($wechat['invite_code'])){
////                    $is_invite = model('User')->isInvite($wechat['invite_code']);  //临时解决邀请问题
////                    if($is_invite){
////                        model('UserLevel')->addLevel($last_id,$is_invite);
////                    }
////                }
//            }
//        } else { //老用户更新
//            $updata['nickname'] = $wechat['nickname'];
//            $updata['avatar'] = $wechat['avatar'];
//            $updata['login_time'] = time();
//            $updata['login_ip'] = request()->ip();
//            $updata['unionid'] = $wechat['unionid'];//unionid
//            if ($is_miniapp) {
//                $updata['session_key'] = $wechat['session_key'];
//                $updata['miniapp_uid'] = $wechat['miniapp_uid'];
//                !empty($wechat['official_uid']) && $updata['official_uid'] = $wechat['official_uid'];
//            }
//            if (!$is_miniapp) $updata['official_uid'] = $wechat['official_uid'];
//            $is_invite = $wechat['invite_code'] ? self::isInvite($wechat['invite_code'], $wechat['miniapp_id']) : false;  //查邀请码是否有效
//            if ($is_invite) {
//                if (!$info['pid']) $updata['pid'] = de_code($wechat['invite_code']);//注册用户加入上级推荐人
//            }
//
//            self::where(['id' => $info['id']])->data($updata)->update();
//            $last_id = $info->id;
//
//            /**-------------20200910 jyk 更新成功后调用事件 start-----------------**/
//            $user = self::find($info->id);
//            //用户更新成功后事件
//            event('UserUpdateSuccess', [$user, $type]);
//            /**-------------20200910 jyk 更新成功后调用事件 end-----------------**/
//        }
//        return $last_id;
//    }

    /**
     * 通过微信注册或更新
     * @param array $wechat
     * @param string $type mini_program小程序  official公众号  app其他
     * @return 成功后返回用户的ID
     */
    public static function wechatReg(array $wechat, $type = 'mini_program', $trans = false)
    {
        //参数
        $data = [];
        $updata = [];
        $data['member_miniapp_id'] = $wechat['miniapp_id'];//MemberMiniapp表id
        $data['nickname'] = $wechat['nickname'];//昵称
        $data['avatar'] = $wechat['avatar']; //头像
        $data['unionid'] = $wechat['unionid'];//unionid
        $data['login_time'] = time(); //登陆时间
        $data['update_time'] = time(); //更新时间
        $data['login_ip'] = request()->ip();  //登录ip
        if ($type == 'mini_program') {//小程序
            $data['session_key'] = $wechat['session_key']; //小程序session_key
            $data['miniapp_uid'] = $wechat['miniapp_uid']; //小程序用户id
        } elseif ($type == 'official') {//公众号
            $data['official_uid'] = $wechat['official_uid'];//公众号openid
        } else {
            //app和其他
            $data['username'] = $wechat['username'];//公众号openid
            $data['password'] = $wechat['password'];
        }
        $condition['member_miniapp_id'] = $wechat['miniapp_id']; //区分哪个应用

        //小程序和公众号
        if($type !='app'){
            $userModel = self::getBaseWhere($wechat);
            $info = $userModel->findOrEmpty();
            //如果没传手机号又查不到注册的账号或账号里也没手机号
            if(!$wechat['mobile']){
                if(!$info)return self::setError('请提交手机号', 400832);
                if(!$info['mobile'])return self::setError('请提交手机号', 400832);
                //账号里有手机号
                $wechat['mobile'] = $info['mobile'];
            }
        }

        /**
         * 先查手机号是否存在
        如果手机号不存在
        {
        账号存在   ，更新手机号
        账号不存在，创建新账号
        }
        如果手机号存在 ，只做更新操作
        {
        对应的id存在   ，不合法，退出流程
        对应的id不存在，合法   ，更新操作
        }
         */
        $mobileUser = $userModel = self::where($condition)->where('mobile',$wechat['mobile'])->findOrEmpty();
        // 如果手机号存在,只做更新操作
        if(!$mobileUser->isEmpty()){
            if ($type == 'mini_program') {  //小程序
                //账号存在并且不是自己
                if($mobileUser['miniapp_uid']&&$mobileUser['miniapp_uid']!=$wechat['miniapp_uid'])return self::setError('手机号已被绑定，请使用其他手机号', 400832);

            } elseif ($type == 'official') { //公众号
                //账号存在并且不是自己
                if($mobileUser['official_uid']&&$mobileUser['official_uid']!=$wechat['official_uid'])return self::setError('手机号已被绑定，请使用其他手机号', 400832);
            }
            $info = $mobileUser;
        }


        if ($trans) {
            self::startTrans();
        }
        $res = true;
        try {


            if ($info->isEmpty()) {//新注册用户
                $data['mobile'] = $wechat['mobile'];
                $is_insert = true;
                //用户在小程序应用设置里面进行公众号绑定操作
                if ($type == 'mini_program' && !empty($wechat['official_uid'])) {

                    if(!empty($wechat['official_uid'])){
                        //绑定公众号需满足该公众号未被自己绑定并没有被其他人使用
                        $official_info = self::where('member_miniapp_id',$wechat['miniapp_id'])->where('official_uid',$wechat['official_uid'])->find();
                        if($official_info)return self::setError('公众号已被其他用户绑定，请联系客服咨询');
                        $data['official_uid'] = $wechat['official_uid'];
                    }
//                    $official_info = self::where(['member_miniapp_id' => $wechat['miniapp_id'], 'miniapp_uid' => $wechat['miniapp_uid']])->find();
//                    if ($official_info) {
//                        $is_insert = false;
//                        $last_id = $official_info['id'];
//                        self::update(['id' => $last_id, 'official_uid' => $wechat['official_uid']]);
//                    }
                }
                //判断是否需要插入数据
                if ($is_insert) {
                    $data['create_time'] = time();
                    $is_invite = $wechat['invite_code'] ? self::isInvite($wechat['invite_code'], $wechat['miniapp_id']) : false;  //查邀请码是否有效
                    if ($is_invite) {
                        $data['pid'] = de_code($wechat['invite_code']);//注册用户加入上级推荐人
                    }
                    $last_id = self::insertGetId($data);
                    if ($last_id) {
                        self::where('id', $last_id)->data(['invite_code' => en_code($last_id)])->update();//每个人的邀请码是根据ID生成的可解密code
                        /**-------------20200910 jyk 注册成功后创建对应应用的用户副表 start-----------------**/
                        $user = self::find($last_id);
                        //用户注册成功后事件
                        event('UserRegisterSuccess', [$user, $type]);
                        /**-------------20200910 jyk 注册成功后创建对应应用的用户副表 end-----------------**/
                    }
//                //添加用户邀请来源
//                if(!empty($wechat['invite_code'])){
//                    $is_invite = model('User')->isInvite($wechat['invite_code']);  //临时解决邀请问题
//                    if($is_invite){
//                        model('UserLevel')->addLevel($last_id,$is_invite);
//                    }
//                }
                }
            } else { //老用户更新
                $updata['mobile'] = $wechat['mobile'];
                $updata['nickname'] = $wechat['nickname'];
                $updata['avatar'] = $wechat['avatar'];
                $updata['login_time'] = time();
                $updata['login_ip'] = request()->ip();
                $updata['unionid'] = $wechat['unionid'];//unionid
                if ($type == 'mini_program') {
                    $updata['session_key'] = $wechat['session_key'];
                    $updata['miniapp_uid'] = $wechat['miniapp_uid'];
//                    !empty($wechat['official_uid']) && $updata['official_uid'] = $wechat['official_uid'];
                    if(!empty($wechat['official_uid'])){
                        //绑定公众号需满足该公众号未被自己绑定并没有被其他人使用
                        $official_info = self::where('member_miniapp_id',$wechat['miniapp_id'])->where('official_uid',$wechat['official_uid'])->find();
                        if($official_info&&$official_info['id']!=$info['id'])return self::setError('公众号已被其他用户绑定，请联系客服咨询');
                        $updata['official_uid'] = $wechat['official_uid'];
                    }

                }
                if ($type == 'official') $updata['official_uid'] = $wechat['official_uid'];
                $is_invite = $wechat['invite_code'] ? self::isInvite($wechat['invite_code'], $wechat['miniapp_id']) : false;  //查邀请码是否有效
                if ($is_invite) {
                    if (!$info['pid']) $updata['pid'] = de_code($wechat['invite_code']);//注册用户加入上级推荐人
                }

                self::where(['id' => $info['id']])->data($updata)->update();
                $last_id=  $info->id;

                /**-------------20200910 jyk 更新成功后调用事件 start-----------------**/
                $user = self::find($info->id);
                //用户更新成功后事件
                event('UserUpdateSuccess', [$user, $type]);
                /**-------------20200910 jyk 更新成功后调用事件 end-----------------**/
            }


            $res = $res && true;

            if ($trans) {
                self::checkTrans($res);
            }
        } catch (\Exception $e) {
            if ($trans) {
                self::rollback();
            }
            return self::setError($e->getMessage());
        }
        if (!$res) return self::setError('关注/取消关注失败');

        return $last_id;
    }


    /**
     * TODO更新安全密码
     * @param array $param 更新的用户信息
     */
    public static function updateSafePasspord(int $uid, string $safe_password)
    {
        $data['safe_password'] = password_hash(md5($safe_password), PASSWORD_DEFAULT);
        return self::where(['id' => $uid])->update($data);
    }

    /**
     * 修改登录密码
     * @access public
     */
    public function upLoginPasspowrd(int $uid, string $password)
    {
        $data['password'] = password_hash(md5($password), PASSWORD_DEFAULT);
        return self::where(['id' => $uid])->update($data);
    }

    /**
     * 锁定用户
     * @param integer $id
     */
    public static function lockUser(int $appid, int $id)
    {
        $result = self::where(['member_miniapp_id' => $appid, 'id' => $id])->find();
        if ($result->is_delete >= 1) {
            return FALSE;
        }
        $result->status = $result->status ? 0 : 1;
        return $result->save();
    }

    /**
     * 登录用户ID
     */
    public static function edit(array $data, int $id)
    {
        return User::where(['id' => $id])->update($data);
    }

    /**
     * 作废
     * @param integer $id
     */
    public static function isDelete(int $appid, int $id)
    {
        $result = self::where(['member_miniapp_id' => $appid, 'id' => $id])->find();
        if ($result->is_delete >= 1) {
            return FALSE;
        }
        $result->status = 1;
        $result->is_delete = 1;
        $result->mobile = '';
        $result->unionid = '';
        $result->official_uid = '';
        $result->miniapp_uid = '';
        return $result->save();
    }





    /**得到账号基础查询条件
     * @param $status
     * @param null $model
     * @param string $alisa
     */
    public static function getBaseWhere($whereData=[],$model=null,$alisa = ''){
        if(!$model){
            $model = new self;
            if($alisa)$model = $model->alias($alisa);
        }
        if($alisa)$alisa = $alisa.'.';
        $model = $model->where("{$alisa}unionid <> '' OR {$alisa}official_uid <> '' OR {$alisa}miniapp_uid <> '' OR {$alisa}mobile <> ''");
        isset($whereData['official_uid']) && $whereData['official_uid'] && $model = $model->where("{$alisa}official_uid", $whereData['official_uid']);
        isset($whereData['miniapp_uid']) && $whereData['miniapp_uid'] && $model = $model->where("{$alisa}miniapp_uid", $whereData['miniapp_uid']);
        isset($whereData['miniapp_id']) && $whereData['miniapp_id'] && $model = $model->where("{$alisa}member_miniapp_id", $whereData['miniapp_id']);
        return $model;
    }
}